angular.module('U9ImHd.services')

.factory('SerialPort', ['$q', 'Connect', 'Config', 'Http', 'APPCONSTANTS', 
    function ($q, Connect, Config, Http, APPCONSTANTS) {
        var spDefer = $q.defer(),
            o = {
                loaded: spDefer.promise
            };

        var _externalDevices = {};

        o.getExternalDevices = function (hasPort) {
            var devices = [];
            hasPort = !!hasPort;
            angular.forEach(_externalDevices, function (value, key) {
                if (hasPort && value.Port) {
                    devices.push({
                        Device: key,
                        Name: value.Name,
                        Port: value.Port
                    });
                } else if (!hasPort && !value.Port) {
                    devices.push({
                        Device: key,
                        Name: value.Name
                    });
                }
            });
            return devices;
        };
        o.bindSerialPort = function (device, port) {
            var defer = $q.defer();

            if (_externalDevices[device]) {
                _externalDevices[device].Port = port;
                return Config.set('externalDevices', _externalDevices); 
            } else {
                defer.resolve();
            }

            return defer.promise;
        };
        o.open = function (devices, options) {
            var defer = $q.defer();

            var ports = [],
                errMsg = "";
            angular.forEach(devices, function (device) {
                var port = _externalDevices[device].Port;
                if (port && port.length > 0) {
                    ports.push(port);
                } else {
                    errMsg += _externalDevices[device].Name + ' ';
                }
            });
            if (errMsg.length > 0) {
                defer.reject(errMsg.substr(0, errMsg.length) + ' 未设置串口');
            } else if (window.cordova && cordova.plugins.SerialPort) {
                cordova.plugins.SerialPort.open(ports, options, function () {
                    defer.resolve();
                }, function () {
                    defer.reject();
                });
            } else {
                defer.reject();
            }

            return defer.promise;
        };
        o.close = function () {
            if (window.cordova && cordova.plugins.SerialPort) {
                cordova.plugins.SerialPort.close();
            }
        };

        init();

        return o;

        function init () {
            Connect.loaded.then(function () {
                return getExternalDevices();
            }).then(function (externalDevice) {
                angular.forEach(externalDevice, function (value, key) {
                    _externalDevices[key] = { Name: value };
                });
                var bindDevices = Config.get('externalDevices', {});
                angular.forEach(bindDevices, function (value, key) {
                    if (value.Port && _externalDevices[key]) {
                        _externalDevices[key].Port = value.Port;
                    }
                });
                return Config.set('externalDevices', _externalDevices);
            }).finally(function () {
                spDefer.resolve();
            });
        }

        function getExternalDevices () {
            return Http.post({
                url: APPCONSTANTS.getExtendEnumURL,
                data: {
                    Parameter: {
                        Code: 'ExternalDevice'
                    }
                },
                ignoreErrorHandler: true
            });
        }
    }
]);
